package sim_interface;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import sim_moteur.Coordonnee;
import sim_moteur.Simulateur;
import sim_moteur.Terrain;
import sim_moteur.element.Chose;
import sim_moteur.element.animeaux.Animal;
import sim_moteur.element.vegetal.Vegetal;
import util.ImageUtil;
import util.SimProperties;

import java.awt.Color;

/**
 * Cette classe gère l'interface de l'application Simulateur Bebitte
 * 
 * @author Martin Simoneau
 * @version 1.0
 * 
 */
public class AppWindow {

	public final static String VEGETAUX_PROPERTY_NAME = "simulation.vegetaux.nombre";
	public final static String ANIMAUX_PROPERTY_NAME = "simulation.animal.nombre";
	public final static String CHOSE_PROPERTY_NAME = "simulation.chose.nombre";

	public final static String DEFAULT_ICON = "../splash.bmp";
	public final static String ANIMAL_30_ICON_NAME = "../animal_100x100.jpg";
	public final static String PLANTE1_100_ICON_NAME = "../plante1_100x100.jpg";
	public final static String PLANTE2_100_ICON_NAME = "../plante2_100x100.jpg";
	public final static String PLANTE3_100_ICON_NAME = "../plante3_100x100.jpg";
	public final static String PLANTE4_100_ICON_NAME = "../plante4_100x100.jpg";
	public final static String SOL_30_ICON_NAME = "../sol_100x100.jpg";
	public final static String PIERRE_30_ICON_NAME = "../pierre_100x100.jpg";

	public final static String SOL = "sol";
	public final static String ANIMAL = "animal";
	public final static String VEGETAL = "vegetal";
	public final static String CHOSE = "chose";

	public final static String NAME_PROPERTY = "name";

	private enum ListPosition {
		ANIMAUX(0), VEGETAUX(1), CHOSE(2);
		private int index;

		ListPosition(int index) {
			this.index = index;
		}

		public int getIndex() {
			return index;
		}
	}

	private static ImageIcon ANIMAL_IMAGE;
	private static ImageIcon PIERRE_IMAGE;
	private static ImageIcon PLANTE_IMAGE_1;
	private static ImageIcon PLANTE_IMAGE_2;
	private static ImageIcon PLANTE_IMAGE_3;
	private static ImageIcon PLANTE_IMAGE_4;
	private static ImageIcon SOL_IMAGE;

	private JFrame frmMsdSimulatorApp;
	private final Action startAction = new StartAction();
	private final Action stopAction = new StopAction();
	private final Action stepAction = new StepAction();

	// Properties properties;

	Simulateur sim;
	FournisseurDeChose fournisseur;
	private final Action initAction = new InitialiseAction();
	private JPanel terrainPanel;
	private int largeurBouton;
	private int hauteurBouton;
	private JTextField step;
	private JTree tree;
	private final Action quitAction = new QuitAction();
	private JTextPane textPane;

	private SelectButtonAction boutonAction;
	private Chose choseSelectionnee = null;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					AppWindow window = new AppWindow();
					window.frmMsdSimulatorApp.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public AppWindow() {

		initialize();
	}

	/**
	 * Initialize the contents of the frame. Code généré par le plugin eclipse
	 * WindowBuilder
	 */
	private void initialize() {
		//Le fournisseur de chose est l'alterego du simulateur pour l'affichage
		fournisseur = new FournisseurDeChose() {
			@Override
			public Collection<Vegetal> getVegetaux() {
				return sim.getVegetaux().values();
			}
			
			@Override
			public String getNameForIndex(int index) {
				return sim.getNameForIndex(index);
			}
			
			@Override
			public Collection<Chose> getLesChosesBasiques() {
				return sim.getLesChosesBasiques().values();				
			}
			
			@Override
			public Chose getChose(String name) {
				return sim.getChose(name);	
			}
			
			@Override
			public Collection<Animal> getAnimaux() {
				return sim.getAnimaux().values();				
			}
		};
		stopAction.setEnabled(false);

		frmMsdSimulatorApp = new JFrame();
		frmMsdSimulatorApp.setResizable(false);
		frmMsdSimulatorApp.setTitle("MSD Simulator APP\n");
		frmMsdSimulatorApp.setBounds(100, 100, 799, 705);
		frmMsdSimulatorApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JMenuBar menuBar = new JMenuBar();
		frmMsdSimulatorApp.setJMenuBar(menuBar);

		JMenu mnSimulator = new JMenu("Simulator");
		menuBar.add(mnSimulator);

		JMenuItem mntmQuit = new JMenuItem("Quit");
		mntmQuit.setAction(quitAction);
		mntmQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0));
		mnSimulator.add(mntmQuit);

		JMenuItem mntmStart = new JMenuItem("Start");
		mntmStart.setAction(startAction);
		mntmStart.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0));
		mnSimulator.add(mntmStart);

		JMenuItem mntmStop = new JMenuItem("Stop");
		mntmStop.setAction(stopAction);
		mnSimulator.add(mntmStop);

		JMenuItem mntmSave = new JMenuItem("Save");
		mnSimulator.add(mntmSave);

		JMenuItem menuItem = new JMenuItem("");
		menuBar.add(menuItem);
		frmMsdSimulatorApp.getContentPane().setLayout(null);

		JButton btnStart = new JButton("Start");
		btnStart.setAction(startAction);
		btnStart.setToolTipText("démarrer la simulation");
		btnStart.setBounds(197, 555, 96, 29);
		btnStart.setEnabled(false);
		frmMsdSimulatorApp.getContentPane().add(btnStart);

		JButton btnStop = new JButton("Stop");
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});
		btnStop.setAction(stopAction);
		btnStop.setBounds(531, 555, 86, 29);
		frmMsdSimulatorApp.getContentPane().add(btnStop);

		JButton btnStep = new JButton("step");
		btnStep.setAction(stepAction);
		btnStep.setBounds(287, 555, 96, 29);
		frmMsdSimulatorApp.getContentPane().add(btnStep);

		JButton btnNewButton = new JButton("Init");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});
		btnNewButton.setAction(initAction);
		btnNewButton.setBounds(613, 555, 117, 29);
		frmMsdSimulatorApp.getContentPane().add(btnNewButton);

		terrainPanel = new JPanel();
		terrainPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		terrainPanel.setBounds(199, 6, 550, 550);
		frmMsdSimulatorApp.getContentPane().add(terrainPanel);
		terrainPanel.setLayout(new GridLayout(1, 0, 0, 0));

		step = new JTextField();
		step.setEnabled(false);
		step.setEditable(false);
		step.setToolTipText("le pas de temps en cours de simulation");
		step.setText("0");
		step.setBounds(114, 260, 74, 28);
		frmMsdSimulatorApp.getContentPane().add(step);
		step.setColumns(10);
		step.setHorizontalAlignment(JTextField.CENTER);

		JLabel lblNewLabel = new JLabel("pas de temps");
		lblNewLabel.setBounds(16, 266, 96, 16);
		frmMsdSimulatorApp.getContentPane().add(lblNewLabel);

		JPanel panel = new JPanel();
		panel.setBackground(Color.LIGHT_GRAY);
		panel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null,
				null));
		panel.setBounds(16, 6, 169, 242);
		frmMsdSimulatorApp.getContentPane().add(panel);

		JLabel lblContenus = new JLabel("Contenus        ");
		lblContenus.setBounds(12, 12, 92, 16);
		panel.setLayout(null);
		panel.add(lblContenus);

		tree = new JTree();
		tree.setBorder(null);
		tree.setBounds(12, 144, 139, 81);
		tree.setMaximumSize(new Dimension(100, 1000));
		tree.addTreeSelectionListener(new TreeSelectionListener() {
			public void valueChanged(TreeSelectionEvent e) {
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) getTree()
						.getLastSelectedPathComponent();
				String name = null;
				if (node != null && node.isLeaf() && fournisseur != null) {
					name = (String) node.getUserObject();
					choseSelectionnee = fournisseur.getChose(name);
					afficheSelectionInfo();
				}
			}
		});
		tree.setRootVisible(false);
		tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("JTree") {
			private static final long serialVersionUID = 3914476978593327206L;

			{
				DefaultMutableTreeNode animauxNode = new DefaultMutableTreeNode(
						"Animaux");
				animauxNode.setAllowsChildren(true);
				DefaultMutableTreeNode vegetauxNode = new DefaultMutableTreeNode(
						"Vegetaux");
				animauxNode.setAllowsChildren(true);
				DefaultMutableTreeNode chosesNode = new DefaultMutableTreeNode(
						"Choses");
				animauxNode.setAllowsChildren(true);
				add(animauxNode);
				add(vegetauxNode);
				add(chosesNode);
			}
		}));
		tree.setShowsRootHandles(true);

		JScrollPane scrollPane = new JScrollPane(tree);
		scrollPane.setBorder(null);
		scrollPane.setViewportBorder(new BevelBorder(BevelBorder.LOWERED, null,
				null, null, null));
		scrollPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane.setBounds(5, 40, 158, 196);
		panel.add(scrollPane);

		JPanel panel_1 = new JPanel();
		panel_1.setBackground(Color.LIGHT_GRAY);
		panel_1.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null,
				null, null));
		panel_1.setBounds(16, 296, 169, 249);
		frmMsdSimulatorApp.getContentPane().add(panel_1);
		panel_1.setLayout(null);

		JLabel lblInformation = new JLabel("Informations");
		lblInformation.setBounds(6, 6, 157, 16);
		panel_1.add(lblInformation);

		textPane = new JTextPane();
		textPane.setBounds(6, 34, 157, 209);
		panel_1.add(textPane);

		int xSize = Terrain.getInstance().getXSize();
		int ySize = Terrain.getInstance().getYSize();

		int largeurPaneauTerrain = terrainPanel.getWidth();
		int hauteurPaneauTerrain = terrainPanel.getHeight();
		largeurBouton = largeurPaneauTerrain / xSize;
		hauteurBouton = hauteurPaneauTerrain / ySize;

		boutonAction = new SelectButtonAction();
		
		initImageIcon();
	}

	public void initSimulation() {
		// On crée un nouveau simulateur au besoin
		if (sim == null) {
			sim = new Simulateur();
		} else {
			sim.init();
		}
		// On configure le simulateur
		configureSimulation();

		// On crée la vue du simulateur
		createSimViews();
		rafraichitTreeView();
	}

	/**
	 * Configure les paramètres de la simulation. Lecture du fichier de
	 * propriétés et inscription des propriétés dans la simulation.
	 */
	public void configureSimulation() {
		// configuration dans le fichier de simulation
		SimProperties props = SimProperties.getInstance();
		int nombreAnimaux = props.getIntProperty(ANIMAUX_PROPERTY_NAME);
		sim.ajouteChoseGenerique(Simulateur.ChosesPossibles.ANIMAL,
				nombreAnimaux);
		int nombreVegetaux = props.getIntProperty(VEGETAUX_PROPERTY_NAME);
		sim.ajouteChoseGenerique(Simulateur.ChosesPossibles.VEGETAL,
				nombreVegetaux);
		int nombreChoses = props.getIntProperty(CHOSE_PROPERTY_NAME);
		sim.ajouteChoseGenerique(Simulateur.ChosesPossibles.CHOSE, nombreChoses);
	}

	/**
	 * Affiche les informations de la classe Chose sélectionnée.
	 */
	private void afficheSelectionInfo() {
		String message = "aucune information\n";
		if (choseSelectionnee != null) {
			message = choseSelectionnee.toString();
		}

		Document doc = getTextPane().getDocument();
		try {
			doc.remove(0, doc.getLength());
			doc.insertString(0, message, null);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Remet à jour l'arbre contenant les éléments simulés
	 */
	private void rafraichitTreeView() {

		DefaultTreeModel model = (DefaultTreeModel) getTree().getModel();
		DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();

		// On insère les animaux dans l'arbre de gauche
		DefaultMutableTreeNode animauxNode = (DefaultMutableTreeNode) root
				.getChildAt(ListPosition.ANIMAUX.getIndex());

		// il faut effacer ceux qui sont déjà présents avant de rafraichir.
		animauxNode.removeAllChildren();
		for (Animal animal : fournisseur.getAnimaux()) {
			animauxNode.add(new DefaultMutableTreeNode(animal.getName()));
		}

		// On insère les vegetaux dans l'arbre de gauche
		DefaultMutableTreeNode vegetauxNode = (DefaultMutableTreeNode) root
				.getChildAt(ListPosition.VEGETAUX.getIndex());
		vegetauxNode.removeAllChildren();
		for (Vegetal vegetal : fournisseur.getVegetaux()) {
			vegetauxNode.add(new DefaultMutableTreeNode(vegetal.getName()));
		}
		model.reload();
	}

	/**
	 * Crée la vue principale. Cette vue contient l'état de la simulation pour
	 * un pas de temps donné. La méthpde efface tout les boutons qui étaient
	 * présents dans la vue avant l'appel.
	 */
	private void createSimViews() {
		Terrain terrain = Terrain.getInstance();
		int xSize = terrain.getXSize();
		int ySize = terrain.getYSize();
		terrainPanel.setLayout(new GridLayout(ySize, xSize, 1, 1));
		terrainPanel.removeAll();
		creeTousLesBoutonsDuSol(xSize, ySize);

		// créer les boutons des éléments simulés
		replaceBoutonAvecAnimaux();
		replaceBoutonDeVegetal();
		replaceBoutonDeChose();

		terrainPanel.setVisible(true);
		frmMsdSimulatorApp.setVisible(true);
	}

	/**
	 * Remplace les boutons de sols où il y a des pierres en boutons de chose.
	 */
	private void replaceBoutonDeChose() {
		for (Chose chose : fournisseur.getLesChosesBasiques()) {
			int index = Terrain.convertCoord(chose.getCoordonnees());
			replaceBouton(index, PIERRE_IMAGE, CHOSE);
		}
	}

	/**
	 * Remplace les boutons de sols où il y a des animaux en boutons d'animaux.
	 */
	private void replaceBoutonAvecAnimaux() {
		for (Animal animal : fournisseur.getAnimaux()) {
			int index = Terrain.convertCoord(animal.getCoordonnees());
			replaceBouton(index, ANIMAL_IMAGE, ANIMAL);
		}
	}

	/**
	 * Remplace les boutons de sols où il y a des végétaux en boutons de
	 * vegetal.
	 */
	private void replaceBoutonDeVegetal() {
		for (Vegetal vegetal : fournisseur.getVegetaux()) {
			int index = Terrain.convertCoord(vegetal.getCoordonnees());
			ImageIcon icon;
			if (vegetal.getVie() > Vegetal.VIE_MAX) {
				icon = PLANTE_IMAGE_4;
			} else if (vegetal.getVie() > Vegetal.VIE_MAX * 3f / 4f) {
				icon = PLANTE_IMAGE_3;
			} else if (vegetal.getVie() > Vegetal.VIE_MAX / 2) {
				icon = PLANTE_IMAGE_2;
			} else {
				icon = PLANTE_IMAGE_1;
			}
			replaceBouton(index, icon, VEGETAL);
		}
	}

	/**
	 * Dessine les boutons formant le terrain.
	 */
	private void dessineTerrain() {
		Terrain terrain = Terrain.getInstance();
		terrainPanel.removeAll();
		int xSize = terrain.getXSize();
		int ySize = terrain.getYSize();

		creeTousLesBoutonsDuSol(xSize, ySize);

		replaceBoutonDeChose();
		replaceBoutonDeVegetal();
		replaceBoutonAvecAnimaux();

		this.frmMsdSimulatorApp.revalidate();
		this.frmMsdSimulatorApp.repaint();

	}

	public void initImageIcon() {
		int largeurTerrain = terrainPanel.getWidth();
		int hauteurTerrain = terrainPanel.getHeight();
		int xSize = Terrain.getInstance().getXSize();
		int ySize = Terrain.getInstance().getYSize();

		int height = hauteurTerrain / ySize;
		int width = largeurTerrain / xSize;
		try {
			// On prépare les images de la bonne dimension pour les boutons du
			// terrain
			BufferedImage animalBufImage = ImageIO.read(getClass()
					.getResourceAsStream(ANIMAL_30_ICON_NAME));
			ANIMAL_IMAGE = new ImageIcon(ImageUtil.resizeImage(animalBufImage,
					width, height));

			BufferedImage pierreBufImage = ImageIO.read(getClass()
					.getResourceAsStream(PIERRE_30_ICON_NAME));
			PIERRE_IMAGE = new ImageIcon(ImageUtil.resizeImage(pierreBufImage,
					width, height));

			BufferedImage solBufImage = ImageIO.read(getClass()
					.getResourceAsStream(SOL_30_ICON_NAME));
			SOL_IMAGE = new ImageIcon(ImageUtil.resizeImage(solBufImage, width,
					height));

			BufferedImage plante1BufImage = ImageIO.read(getClass()
					.getResourceAsStream(PLANTE1_100_ICON_NAME));
			PLANTE_IMAGE_1 = new ImageIcon(ImageUtil.resizeImage(
					plante1BufImage, width, height));

			BufferedImage plante2BufImage = ImageIO.read(getClass()
					.getResourceAsStream(PLANTE2_100_ICON_NAME));
			PLANTE_IMAGE_2 = new ImageIcon(ImageUtil.resizeImage(
					plante2BufImage, width, height));

			BufferedImage plante3BufImage = ImageIO.read(getClass()
					.getResourceAsStream(PLANTE3_100_ICON_NAME));
			PLANTE_IMAGE_3 = new ImageIcon(ImageUtil.resizeImage(
					plante3BufImage, width, height));

			BufferedImage plante4BufImage = ImageIO.read(getClass()
					.getResourceAsStream(PLANTE4_100_ICON_NAME));
			PLANTE_IMAGE_4 = new ImageIcon(ImageUtil.resizeImage(
					plante4BufImage, width, height));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Retire de la vue la chose, si elle est morte.
	 * 
	 * @param chose
	 *            La chose à vérifier
	 * @param dimensionX
	 *            le nombre de colonnes
	 * @return vrai si la chose est morte
	 */
	private boolean retireMort(Chose chose, int dimensionX) {
		boolean estMort = chose.getCoordonnees().equals(new Coordonnee(-1, -1));
		if (estMort) {
			Coordonnee ancienne = chose.getCoordonneesPrecedentes();
			int index = Terrain.convertCoord(chose.getCoordonneesPrecedentes());
			terrainPanel.remove(index);// On retire l'animal
			// On mets une chose inerte à la place
			creeUnBoutonDeChose(dimensionX, ancienne);
		}
		return estMort;
	}

	/**
	 * Crée des bouton générique de sol. Où il n'y a rien
	 * 
	 * @param xSize
	 *            le nombre de colonnes
	 * @param ySize
	 *            le nombre de rangées
	 */
	private void creeTousLesBoutonsDuSol(int xSize, int ySize) {

		for (int i = 0; i < xSize * ySize; i++) {

			creeBouton(i, SOL_IMAGE);
		}
	}

	/**
	 * Crée un bouton pour une chose, au bon endroit dans la vue principale
	 * 
	 * @param xSize
	 *            le nombre de colonne
	 * @param coordonnee
	 *            l'emplacement où mettre la chose
	 */
	private void creeUnBoutonDeChose(int xSize, Coordonnee coordonnee) {
		try {
			Image animalIconImage = ImageIO.read((getClass()
					.getResourceAsStream(PIERRE_30_ICON_NAME)));
			int x = coordonnee.getX();
			int y = coordonnee.getY();
			creeBouton(y * xSize + x, new ImageIcon(animalIconImage));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Crée un bouton avec l'icone choisi.
	 * 
	 * @param count
	 *            l'indice où placer le bouton dans le GridArrayLayour
	 * @param icon
	 */
	private void creeBouton(int count, ImageIcon icon) {
		JButton button = new JButton();
		button.setAction(boutonAction);
		button.setIcon(icon);
		button.setSize(largeurBouton, hauteurBouton);
		String name = fournisseur.getNameForIndex(count);
		if (name == null) {
			name = "S"; // pour le sol
		}
		button.putClientProperty(NAME_PROPERTY, name);

		terrainPanel.add(button, count);
	}

	private void replaceBouton(int count, ImageIcon icon, String name) {
		terrainPanel.remove(count);
		creeBouton(count, icon);
	}

	@Override
	public String toString() {
		String retVal = "";

		int colonne = 0;

		for (int y = 0; y < terrainPanel.getComponentCount(); y++) {

			JButton button = (JButton) terrainPanel.getComponent(y);
			String name = (String) button.getClientProperty(NAME_PROPERTY);
			retVal += name.charAt(0);
			colonne++;
			if (colonne == Terrain.getInstance().getXSize()) {
				retVal += "\n";
				colonne = 0;
			}
		}
		return retVal;
	}

	protected JTree getTree() {
		return tree;
	}

	protected JTextPane getTextPane() {
		return textPane;
	}

	// Inner class
	// ___________________________________________________________________________________________________________________

	/**
	 * Démarrage de la simulation . PAS FONCTIONNEL SANS THREAD
	 */
	private class StartAction extends AbstractAction {

		private static final long serialVersionUID = -8330764364382638699L;

		public StartAction() {
			putValue(NAME, "start");
			putValue(SHORT_DESCRIPTION, "Some short description");
		}

		public void actionPerformed(ActionEvent e) {
			initSimulation();
			while (sim.resteToujoursUnVivant()) {
				sim.step();
				dessineTerrain();
			}
		}
	}

	/**
	 * Arrêt de la simulation . PAS FONCTIONNEL SANS THREAD
	 */
	private class StopAction extends AbstractAction {

		private static final long serialVersionUID = 6013057731532062570L;

		public StopAction() {
			putValue(NAME, "stop");
			putValue(SHORT_DESCRIPTION, "interrompt la boucle de simulation");
		}

		public void actionPerformed(ActionEvent e) {
		}
	}

	/**
	 * Fair avancer la simulation s'un pas de temps.
	 */
	private class StepAction extends AbstractAction {

		private static final long serialVersionUID = 146371914410394656L;

		public StepAction() {
			putValue(NAME, "Step");
			putValue(SHORT_DESCRIPTION, "lance la boucle de simulation");
		}

		public void actionPerformed(ActionEvent e) {
			if (sim == null) {
				initSimulation();
			}

			sim.step();
			sim.enleveMort();
			dessineTerrain();

			// On mets à jour l'Arbre de gauche
			rafraichitTreeView();

			// L'objet Sélectionné a pu se déplacer on doit ajuster la sélection
			afficheSelectionInfo();

			// On affiche de l'info à la console pour valider que la simulation
			// et l'affichage sont cohérents
			step.setText("" + sim.getStep());
			System.out.println("step " + sim.getStep() + "\n" + sim.toString());
			System.out.println("affichage \n" + AppWindow.this.toString());
		}
	}

	/**
	 * Réinitialise la simulation avec les options initiales
	 */
	private class InitialiseAction extends AbstractAction {

		private static final long serialVersionUID = -6045707951643296876L;

		public InitialiseAction() {
			putValue(NAME, "initialise");
			putValue(SHORT_DESCRIPTION, "réinitialise la simulation");
		}

		public void actionPerformed(ActionEvent e) {
			initSimulation();
		}
	}

	/**
	 * Quitte l'application
	 */
	private class QuitAction extends AbstractAction {

		private static final long serialVersionUID = -5093604235680216775L;

		public QuitAction() {
			putValue(NAME, "Quit");
			putValue(SHORT_DESCRIPTION, "Quitter l'application");
		}

		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}

	/*
	 * Réagit lorsque l'utilisateur appuie sur l'un des boutons de la vue
	 * principale.
	 */
	private class SelectButtonAction extends AbstractAction {

		private static final long serialVersionUID = 2462695157562217750L;

		public SelectButtonAction() {
			putValue(SHORT_DESCRIPTION, "sélectionner un bouton l'application");
		}

		public void actionPerformed(ActionEvent e) {
			Object obj = e.getSource();
			if (obj != null && fournisseur != null && obj instanceof JButton) {
				JButton bouton = (JButton) obj;
				String name = (String) bouton.getClientProperty(NAME_PROPERTY);
				choseSelectionnee = fournisseur.getChose(name);
				afficheSelectionInfo();
			}
		}
	}
	
	// Remplace Sim
	public interface FournisseurDeChose {
		public Chose getChose(String name);

		public Collection<Animal> getAnimaux();

		public Collection<Vegetal> getVegetaux();

		public Collection<Chose> getLesChosesBasiques();

		public String getNameForIndex(int index);

		
	}
}
